package com.mspbots.rule.queue.attendance;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.mspbots.api.service.TenantUserService;
import com.mspbots.cw.request.TenantUserConfigurationDTO;
import com.mspbots.rule.exceptions.BaseRule;
import com.mspbots.rule.exceptions.attendance.AttendanceBaseRule;
import com.mspbots.rule.queue.BaseQueue;
import lombok.extern.slf4j.Slf4j;
import org.jeasy.rules.api.Facts;
import org.jeasy.rules.api.Rules;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

/**
 * @ClassName com.mspbots.rule.queue.attendance.AttendanceBaseQueue
 * @Description TODO
 * @Author Jun
 * @Date 2019/9/18 22:24
 * @Version 1.0
 **/
@Slf4j
@Component
public class AttendanceBaseQueue extends BaseQueue {

    @Autowired
    protected ObjectMapper objectMapper;
    @Autowired
    private ThreadPoolTaskExecutor poolTaskExecutor;
    @Autowired
    private TenantUserService tenantUserService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Async
    protected void onRule(String ruleName, TenantUserConfigurationDTO tenantUserConfigurationDTO) {
        try {
            if (checkRule(ruleName, tenantUserConfigurationDTO.getTenantId())) {
//                log.info("Attendance rule [{}] [{}] ", tenantRuleDTO.getRuleId(),tenantUserConfigurationDTO.getId());
                Rules rules = new Rules();
                Class clazz = Class.forName(tenantRuleDTO.getClassName());
                AttendanceBaseRule instance = (AttendanceBaseRule) clazz.getDeclaredConstructor().newInstance();
                instance.init(tenantRuleDTO, messageProducer, messagesService, tenantUserMappingService,
                        tenantConfigurationService, coreClient, objectMapper);
                instance.setTenantUserService(tenantUserService);
                instance.setStringRedisTemplate(stringRedisTemplate);
                instance.initWorkConfig(tenantUserConfigurationDTO);

                rules.register(instance);
                Facts facts = new Facts();
                facts.put(BaseRule.FACT, tenantUserConfigurationDTO);
                rulesEngine.fire(rules, facts);
            }
        } catch (Exception e) {
            log.error("trigger [{}] fire error : {}", ruleName, tenantUserConfigurationDTO.getId());
            e.printStackTrace();
        }

        /*checkRule(ruleName, tenantUserConfigurationDTO.getTenantId())
                .map(ruleDto -> {
                    try {
                        Class clz = Class.forName(ruleDto.getClassName());
                        AttendanceBaseRule instance = (AttendanceBaseRule) clz.getDeclaredConstructor().newInstance();
                        instance.init(ruleDto, messageProducer, messagesService, tenantUserMappingService,
                                tenantConfigurationService, coreClient);
                        instance.setObjectMapper(objectMapper);
                        instance.setTenantUserService(tenantUserService);
                        instance.setStringRedisTemplate(stringRedisTemplate);
                        return instance;
                    } catch (ClassNotFoundException | InstantiationException
                            | InvocationTargetException | NoSuchMethodException
                            | IllegalAccessException e) {
                        return e;
                    }
                })
                .subscribe(instance -> {
                    Rules rules = new Rules();
                    rules.register(instance);
                    Facts facts = new Facts();
                    facts.put(BaseRule.FACT, tenantUserConfigurationDTO);
                    poolTaskExecutor.execute(() -> {
                        rulesEngine.fire(rules, facts);
                    });
                    *//*new Thread(new Runnable() {
                        @Override
                        public void run() {
                            rulesEngine.fire(rules, facts);
                        }
                    }).start();*//*

                }, err -> log.error("onRule is error {}", err.getMessage()));*/

    }

}
